<script lang="tsx" setup>
/*
 * index
 * 组件用途：
 * 创建日期： 2024/04/07
 * 作者： 谭期元
 */
import type { InputProps, TableProps, TableRowData } from 'tdesign-vue-next'
import {
  UserIcon,
  UserBusinessIcon,
  UserListIcon,
  RollbackIcon,
  AddIcon
} from 'tdesign-icons-vue-next'
import { useUserStore } from '@/stores'
import type { PageModel } from '@/api/models/baseModel'
import type { UserModel } from '@/api/models/userModel'
import { deleteById, postAdd, putById } from '@/api/user'

const userStore = useUserStore()
const statusNameListMap: Record<number, { label: string; theme: string; icon: any }> = {
  1: {
    label: '管理员',
    theme: 'primary',
    icon: <UserIcon />
  },
  0: {
    label: '普通用户',
    theme: 'success',
    icon: <UserBusinessIcon />
  }
}
type TablePage = { current: number; pageSize: number }
const route = useRoute()
const router = useRouter()
const tableRef = ref()

// 弹出框
const dialogVisibleRef = ref(false)
const confirmLoadingRef = ref(false)
const dialogTitleRef = ref('用户详情')
const fmModel = {
  id: 0,
  name: '',
  email: '',
  password: '',
  createdAt: '',
  updatedAt: '',
  username: '',
  isAdmin: 0,
  realName: '',
  activatedAt: ''
}
const dialogContentRef = ref<UserModel>({ ...fmModel })
// 编辑
const confirmBtnRef = ref<any>()
const cancelBtnRef = ref<any>()
// 删除
const deleteBtnLoadingRefs = ref<Record<number | string, boolean>>({})
// 搜索
const searchRef = ref('')
// 表格
const tableData = ref<Array<UserModel>>([])
const tableLoadingRef = ref(false)
const viewHeight = ref(window.innerHeight)
const stripe = ref(true)
const bordered = ref(true)
const hover = ref(false)
const size = ref<TableProps['size']>('medium')
const showHeader = ref(true)
const columns = ref<TableProps['columns']>([
  {
    title: 'No',
    colKey: 'serial-number',
    width: 100
  },
  {
    colKey: 'email',
    title: '邮箱地址',
    sortType: 'all',
    sorter: (a, b) => a.email.localeCompare(b.email)
  },
  {
    colKey: 'username',
    title: '用户名',
    sortType: 'all',
    sorter: (a, b) => a.email.localeCompare(b.email)
  },
  {
    colKey: 'isAdmin',
    title: '用户身份',
    sortType: 'all',
    sorter: (a, b) => a.isAdmin - b.isAdmin,
    cell: (h, { row }) => {
      return (
        <t-tag shape="round" theme={statusNameListMap[row.isAdmin].theme} variant="light-outline">
          {statusNameListMap[row.isAdmin].icon}
          {statusNameListMap[row.isAdmin].label}
        </t-tag>
      )
    }
  },
  {
    colKey: 'activatedAt',
    title: '激活时间',
    sortType: 'all',
    sorter: (a, b) => new Date(a.activatedAt).getTime() - new Date(b.activatedAt).getTime()
  },
  {
    colKey: 'updatedAt',
    title: '更新时间',
    sortType: 'all',
    sorter: (a, b) => new Date(a.updatedAt).getTime() - new Date(b.updatedAt).getTime()
  },
  {
    colKey: 'operation',
    title: '操作',
    foot: '-'
  }
])

const sort = ref<TableProps['sort']>()

const pagination: TableProps['pagination'] = {
  defaultCurrent: Number(route.query?.current),
  defaultPageSize: Number(route.query?.limit),
  total: 0
}

const handleRowClick: TableProps['onRowClick'] = (e) => {
  console.log(e)
}

const rehandleChange: TableProps['onChange'] = (changeParams) => {
  if (changeParams.pagination) {
    // 翻页
    const { current, pageSize } = changeParams.pagination as TablePage
    router.replace({ path: '/user', query: { current, limit: pageSize } })
    handleLoad({
      current,
      pageSize
    })
  }
}

const handleDetail = (context: TableRowData) => {
  Object.assign(dialogContentRef.value, context)
  dialogTitleRef.value = '用户详情'
  confirmBtnRef.value = cancelBtnRef.value = null
  dialogVisibleRef.value = true
}

const handleEdit = (context: TableRowData) => {
  Object.assign(dialogContentRef.value, context, { password: '' })
  dialogTitleRef.value = '编辑用户信息'
  confirmBtnRef.value = '保存'
  cancelBtnRef.value = '取消'
  dialogVisibleRef.value = true
}

const handleSave = async () => {
  try {
    confirmLoadingRef.value = true
    const func = dialogTitleRef.value === '新增用户' ? postAdd : putById
    const { fail, message } = await func({ ...dialogContentRef.value })
    if (!fail) {
      MessagePlugin.success({ content: message })
      executed()
      dialogVisibleRef.value = false
      return
    }
    MessagePlugin.error({ content: message })
  } finally {
    confirmLoadingRef.value = false
  }
}

const handleDelete = async (context: TableRowData) => {
  try {
    deleteBtnLoadingRefs.value[context.id as number] = true
    const { fail, message } = await deleteById(context.id)
    if (!fail) {
      MessagePlugin.success({ content: message })
      executed()
      return
    }
    MessagePlugin.error({ content: message })
  } finally {
    deleteBtnLoadingRefs.value[context.id] = false
  }
}

const handleAdd = () => {
  Object.assign(dialogContentRef.value, { ...fmModel })
  dialogTitleRef.value = '新增用户'
  confirmBtnRef.value = '立即新增'
  cancelBtnRef.value = '取消'
  dialogVisibleRef.value = true
}

const handleSearch: InputProps['onEnter'] = (value) => {
  if (!value) return
  const { limit } = route.query as unknown as PageModel
  router.replace({ path: '/user', query: { current: 1, limit, key: value } })
  handleLoad({
    current: 1,
    pageSize: 50,
    key: value as string
  })
}

const handleReset = () => {
  const { limit } = route.query as unknown as PageModel
  searchRef.value = ''
  router.replace({ path: '/user', query: { current: 1, limit } })
  handleLoad({
    current: 1,
    pageSize: 50
  })
}

const handleLoad = async ({ current, pageSize, key }: TablePage & { key?: string }) => {
  // console.log(current, pageSize)
  try {
    tableLoadingRef.value = true
    const { data } = await userStore.list(current, pageSize, key)
    tableData.value.length = 0
    data.list.forEach((it) => tableData.value.push(it))
    pagination.total = data.total
  } finally {
    tableLoadingRef.value = false
  }
}

const sortChange: TableProps['onSortChange'] = (sortVal, options) => {
  console.log('sort-change', sortVal, options.currentDataSource)
  sort.value = sortVal
  tableData.value = options.currentDataSource as Array<UserModel>
}

const executed = async () => {
  const { current, limit } = route.query as unknown as PageModel
  handleLoad({
    current,
    pageSize: limit
  })
}

onMounted(executed)
</script>

<template>
  <div>
    <div class="text-h5 py-4 pl-4">
      <div class="d-flex justify-space-between align-center px-2">
        <div>
          <UserListIcon class="mr-2" />
          用户管理
        </div>
        <t-space class="d-flex align-end">
          <t-button @click="handleAdd">
            <template #icon>
              <AddIcon />
            </template>
            新增
          </t-button>
          <t-button theme="default" variant="outline" @click="handleReset">
            <template #icon>
              <RollbackIcon />
              重置
            </template>
          </t-button>
          <t-input
            v-model="searchRef"
            clearable
            placeholder="输入关键字，回车..."
            @enter="handleSearch"
          >
            <template #suffixIcon>
              <search-icon :style="{ cursor: 'pointer' }" />
            </template>
          </t-input>
        </t-space>
      </div>
    </div>
    <div class="overflow-auto">
      <t-dialog
        v-model:visible="dialogVisibleRef"
        :cancelBtn="cancelBtnRef"
        :closeOnOverlayClick="false"
        :confirmBtn="confirmBtnRef"
        :confirmLoading="confirmLoadingRef"
        width="50rem"
        @confirm="handleSave"
      >
        <t-descriptions :title="dialogTitleRef" bordered colon>
          <t-descriptions-item label="用户ID">
            {{ dialogContentRef.id ? dialogContentRef.id : '-' }}
          </t-descriptions-item>
          <t-descriptions-item>
            <template #label>
              <span v-if="dialogTitleRef === '新增用户'" class="text-red">*</span>邮箱
            </template>
            <t-input v-if="confirmBtnRef" v-model="dialogContentRef.email" required />
            <div v-else>
              {{ dialogContentRef.email }}
            </div>
          </t-descriptions-item>
          <t-descriptions-item label="用户名">
            <t-input v-if="confirmBtnRef" v-model="dialogContentRef.username" />
            <div v-else>{{ dialogContentRef.username || '暂未设置' }}</div>
          </t-descriptions-item>
          <t-descriptions-item label="是否管理员">
            <t-space v-if="confirmBtnRef">
              <t-radio-group v-model:value="dialogContentRef.isAdmin">
                <t-radio :value="0"> 普通用户</t-radio>
                <t-radio :value="1"> 管理员</t-radio>
              </t-radio-group>
            </t-space>
            <div v-else>
              {{ dialogContentRef.isAdmin ? '是' : '否' }}
            </div>
          </t-descriptions-item>
          <t-descriptions-item label="真实姓名">
            <t-input v-if="confirmBtnRef" v-model="dialogContentRef.realName" />
            <div v-else>{{ dialogContentRef.realName || '暂未设置' }}</div>
          </t-descriptions-item>
          <t-descriptions-item v-if="confirmBtnRef">
            <template #label>
              <span v-if="dialogTitleRef === '新增用户'" class="text-red">*</span>密码
            </template>
            <t-input v-model="dialogContentRef.password" type="password" />
          </t-descriptions-item>
          <t-descriptions-item label="激活时间"
            >{{
              dialogContentRef.createdAt
                ? new Date(dialogContentRef.createdAt).toLocaleString()
                : '-'
            }}
          </t-descriptions-item>
          <t-descriptions-item label="更新时间"
            >{{
              dialogContentRef.updatedAt
                ? new Date(dialogContentRef.updatedAt).toLocaleString()
                : '-'
            }}
          </t-descriptions-item>
          <t-descriptions-item label="激活时间"
            >{{
              dialogContentRef.activatedAt
                ? new Date(dialogContentRef.activatedAt).toLocaleString()
                : '-'
            }}
          </t-descriptions-item>
        </t-descriptions>
      </t-dialog>

      <t-table
        ref="tableRef"
        :bordered="bordered"
        :columns="columns"
        :data="tableData"
        :hover="hover"
        :loading="tableLoadingRef"
        :max-height="`${viewHeight - 185}px`"
        :pagination="pagination"
        :show-header="showHeader"
        :size="size"
        :sort="sort"
        :stripe="stripe"
        cell-empty-content="-"
        lazy-load
        resizable
        row-key="id"
        table-layout="fixed"
        @change="rehandleChange"
        @row-click="handleRowClick"
        @sort-change="sortChange"
      >
        <template #activatedAt="{ row }">
          {{ row.activatedAt ? new Date(row.activatedAt).toLocaleString() : '-' }}
        </template>
        <template #updatedAt="{ row }">
          {{ row.updatedAt ? new Date(row.updatedAt).toLocaleString() : '-' }}
        </template>

        <template #operation="{ row }">
          <t-space>
            <t-link hover="color" theme="primary" @click="handleDetail(row)"> 查看详情</t-link>
            <t-link hover="color" theme="primary" @click="handleEdit(row)"> 编辑</t-link>

            <t-popconfirm
              :content="`确认删除【${row.email}】吗`"
              theme="danger"
              @confirm="handleDelete(row)"
            >
              <t-link :id="`delete-${row.id}`" hover="color" theme="danger"> 删除</t-link>
              <t-loading
                :attach="`#delete-${row.id}`"
                :loading="!!deleteBtnLoadingRefs[row.id]"
                size="small"
              ></t-loading>
            </t-popconfirm>
          </t-space>
        </template>
      </t-table>
    </div>
  </div>
</template>

<style lang="scss" scoped></style>
